<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ASCII 动画</title>
    <link rel="icon" type="image/x-icon" href="../favicon.ico" />
    <style>
      body {
        background: black;
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        overflow: hidden;
        font-family: 'Courier New', Courier, monospace;
      }
      /* ascii动画 */
      .asciibox {
        font-size: 1rem;
        color: #17f700;
        line-height: 1.5rem;
        letter-spacing: 1rem;
      }
    </style>
  </head>
  <body>
    <pre class="asciibox"></pre>

    <!-- ascii 动画 -->
    <script type="module">
      import {
        parseGIF,
        decompressFrames,
      } from 'https://cdn.jsdelivr.net/npm/gifuct-js@2.1.2/+esm'

      const asciibox = {
        container: document.querySelector('.asciibox'),
        height: 0,
        width: 0,
        texts: [],
        scale_num: 1,
        current_text_index: 0,
        init() {
          fetch('./images/doro.gif')
            .then((res) => res.arrayBuffer())
            .then((buffer) => {
              const gif = parseGIF(buffer)
              console.log(gif)

              this.height = gif.lsd.height
              this.width = gif.lsd.width
              decompressFrames(gif, true).forEach((frame) => {
                const canvas = document.createElement('canvas')
                canvas.width = this.width
                canvas.height = this.height
                const ctx = canvas.getContext('2d')
                const image_data = new ImageData(
                  frame.patch,
                  frame.dims.width,
                  frame.dims.height
                )
                ctx.putImageData(image_data, 0, 0)
                this.create_texts(
                  ctx.getImageData(0, 0, this.width, this.height).data
                )
              })
              setInterval(() => {
                this.current_text_index =
                  (this.current_text_index + 1) % (this.texts.length - 1)
                this.container.innerText = this.texts[this.current_text_index]
              }, 55)
            })
        },
        create_texts(data) {
          let text = ''
          const levels = [['0', '1'], ['.', '-'], ['']]
          for (let y = 0; y < this.height; y += this.scale_num) {
            let row = ''
            for (let x = 0; x < this.width; x += this.scale_num) {
              const i = (y * this.width + x) * 4
              const avg = (data[i] + data[i + 1] + data[i + 2]) / 3
              const level =
                levels[Math.floor((avg / 255) * (levels.length - 1))]
              const char = level[parseInt(Math.random() * level.length)]
              row += char
            }
            text += row + '\n'
          }
          this.texts.push(text)
        },
      }

      asciibox.init()
    </script>
  </body>
</html>
